package com.synnapps.carouselview;

import ohos.agp.components.Component;

/**
 * PageSlider切换动画转换器
 */
public class CarouselViewTransformer implements PageTransformer {
    /**
     * FLOW动画
     */
    public static final int FLOW = 0;
    /**
     * SLIDE_OVER动画
     */
    public static final int SLIDE_OVER = 1;
    /**
     * DEPTH动画
     */
    public static final int DEPTH = 2;
    /**
     * ZOOM动画
     */
    public static final int ZOOM = 3;
    /**
     * 默认动画
     */
    public static final int DEFAULT = -1;
    private static final double MIN_SCALE_DEPTH = 0.75f;
    private static final double MIN_SCALE_ZOOM = 0.85f;
    private static final double MIN_ALPHA_ZOOM = 0.5f;
    private static final double SCALE_FACTOR_SLIDE = 0.85f;
    private static final double MIN_ALPHA_SLIDE = 0.35f;
    private final int transformerType;
    private double alpha;
    private double scale;
    private double translationX;

    /**
     * 构造方法
     *
     * @param transformerType 动画类型
     */
    public CarouselViewTransformer(int transformerType) {
        this.transformerType = transformerType;
    }

    @Override
    public void transformPage(Component page, float position) {
        switch (transformerType) {
            case FLOW:
                page.setRotation(position * -30f);
                return;
            case SLIDE_OVER:
                if (position < 0 && position >= -1) {
                    getSlideOver(page, position);
                } else {
                    scale = 1;
                    alpha = 1;
                    translationX = 0;
                }
                break;

            case DEPTH:
                if (position >= 0 && position <= 1) {
                    alpha = (1 - (double) position);
                    scale = MIN_SCALE_DEPTH + (1 - MIN_SCALE_DEPTH) * (1 - (double) Math.abs(position));
                    translationX = (page.getWidth() * -position);
                } else {
                    alpha = 1;
                    scale = 1;
                    translationX = 0;
                }
                break;

            case ZOOM:
                if (position >= -1 && position <= 1) {
                    getZoom(page, position);

                } else {
                    alpha = 1;
                    scale = 1;
                    translationX = 0;
                }
                break;

            default:
                return;
        }
        page.setAlpha((float) alpha);
        page.setTranslationX((float) translationX);
        page.setScaleX((float) scale);
        page.setScaleY((float) scale);
    }

    private void getZoom(Component page, float position) {
        scale = Math.max(MIN_SCALE_ZOOM, 1 - (double) Math.abs(position));
        alpha = MIN_ALPHA_ZOOM +
                (scale - MIN_SCALE_ZOOM) / (1 - MIN_SCALE_ZOOM) * (1 - MIN_ALPHA_ZOOM);
        double vMargin = page.getHeight() * (1 - scale) / 2;
        double hMargin = page.getWidth() * (1 - scale) / 2;
        if (position < 0) {
            translationX = (hMargin - vMargin / 2);
        } else {
            translationX = (-hMargin + vMargin / 2);
        }
    }

    private void getSlideOver(Component page, float position) {
        alpha = Math.max(MIN_ALPHA_SLIDE, 1 - (double) Math.abs(position));
        scale = Math.abs((double) Math.abs(position) - 1) * (1.0f - SCALE_FACTOR_SLIDE) + SCALE_FACTOR_SLIDE;
        int pageWidth = page.getWidth();
        float translateValue = position * -pageWidth;
        if (translateValue > -pageWidth) {
            translationX = translateValue;
        } else {
            translationX = 0;
        }
    }
}
